package com.gk.panda.apis.util;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * 电子围栏加密工具
 */
public class ElecRailUtils {

    private static final String DEFAULT_CHARSET_NAME = "UTF-8";
    //加密算法RSA
    public static final String KEY_ALGORITHM = "RSA";
    //Cipher转换名称
    public static final String TRANSFORMATION_NAME = "RSA/ECB/PKCS1Padding";
    //RSA最大加密明文大小
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * <p>
     * 私钥加密
     * </p>
     *
     * @param data       源数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION_NAME);
        cipher.init(Cipher.ENCRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加�?
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    public static String encryptByPrivateKeyStr(String dataStr, String privateKey) throws Exception {
        byte[] data = dataStr.getBytes(DEFAULT_CHARSET_NAME);
        return byteArr2HexStr(encryptByPrivateKey(data, privateKey));
    }


    /**
     * 二进制字节转16进制字符
     */
    public static String byteArr2HexStr(byte[] arrB) throws Exception {
        int iLen = arrB.length;
        StringBuilder sb = new StringBuilder(iLen * 2);
        for (int i = 0; i < iLen; i++) {
            int intTmp = arrB[i];
            while (intTmp < 0) {
                intTmp = intTmp + 256;
            }
            if (intTmp < 16) {
                sb.append("0");
            }
            sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
    }

//    public static void main(String[] args) throws Exception {
//        Map<String,Object>  data=new HashMap<>();//传入参数
//        data.put("AREA_CODE","1111111");
//        data.put("QUERY_DATE","2022110712");
//        data.put("METHOD_TYPE","xxxxxxxxx");
//        String privateKey="MIIC********";//秘钥需要线下获取
//        String todoValue = JSON.toJSONString(data);
//        String miValue = encryptByPrivateKeyStr(todoValue,privateKey);//私加密
//        System.out.println("私钥加密后："+miValue);
//    }

}
